#ifndef _HBFOXLIB_DEFINED
#define _HBFOXLIB_DEFINED

#xtranslate AND => .and.
#xtranslate OR  => .or.


/* messages in FP */
#xtranslate .<!msg!> => :<msg>


/* array declarations */
#xtranslate __FP_DIM( <exp> ) => <exp>
#xtranslate __FP_DIM( <!name!>( <dim,...> ) ) => <name>\[ <dim> \]

/*
#command PUBLIC <var1> [, <varN> ] => ;
        PUBLIC __FP_DIM( <var1> ) [, __FP_DIM(<varN>) ]

#command PRIVATE <var1> [, <varN> ] => ;
         PRIVATE __FP_DIM( <var1> ) [, __FP_DIM( <varN> ) ]
*/

#command DIMENSIONS <!name1!>( <dim1,...> ) [, <!nameN!>( <dimN,...> ) ] => ;
         PRIVATE <name1>\[ <dim1> \] [, <nameN>\[ <dimN> \] ]


/* workaround for problem with command using FIELDS keyword which can
   wrongly translate FIELD->fieldname.
 */
#translate FIELD-><!name!> => _FIELD-><name>


/* commands using FIELDS clause which is not accepted by Clipper */
#command DISPLAY [FIELDS <v,...>] [<off:OFF>] ;
                 [<prn:TO PRINTER>] [TO FILE <(f)>] ;
                 [FOR <for>] [WHILE <while>] [NEXT <next>] ;
                 [RECORD <rec>] [<rest:REST>] [<all:ALL>] => ;
                 __dbList( <.off.>, { <{v}> }, <.all.>, ;
                   <{for}>, <{while}>, <next>, ;
                   <rec>, <.rest.>, <.prn.>, <(f)> )




#command SCATTER FIELDS <f1> [,<fn>]    ;
		 [<mm: MEMO>]           ;
		 [TO] MEMVAR         => ;
		 [ PRIVATE <f1>:=iif(!<.mm.> .and. fieldtype(fieldpos(<"f1">))=="M","", field-><f1>)];
		 [;PRIVATE <fn>:=iif(!<.mm.> .and. fieldtype(fieldpos(<"fn">))=="M","", field-><fn>)]


#command SCATTER FIELDS <f1> [,<fn>]    ;
		 [MEMO]                 ;
		 [TO] MEMVAR BLANK   => ;
         	 [PRIVATE <f1>:=fox_fieldBlank(fieldpos(<"f1">))];
		 [;PRIVATE <fn>:=fox_fieldBlank(fieldpos(<"fn">))]

#command SCATTER [TO] MEMVAR ;
		[<mm: MEMO>]            ;
		[<bb: BLANK>]       =>  ;
                ;PRIVATE ___i,___m  ;
		;FOR ___i:=1 to FCount() 			;
		;	 ___m:=FieldName(___i)        		;
		;        PRIVATE &___m                   	;
		;	IIF(<.bb.>,__mvPut(___m,fox_fieldBlank(___i)),IIF(!<.mm.> .and. FieldType(___i)=="M",__mvPut(___m,""),__mvPut(___m,fieldGet(___i)) ));
		;NEXT 
		    				
		

#command SCATTER TO <arr>;
		[<mm: MEMO>]            ;
		[<bb: BLANK>]       =>  ;
		<arr>:={} 		;	
                ;PRIVATE ___ch;
		;FOR ___ch:=1 TO FCount() ;
		;  IIF(<.bb.>, AAdd(<arr>,fox_fieldBlank(___ch)),IIF(!<.mm.> .and. FieldType(___ch)=="M",AAdd(<arr>,""),AADD(<arr>,FieldGet(___ch))));	
		;NEXT						


#command GATHER MEMVAR FIELDS <f1> [,<fn>]    ;
		 [MEMO]              => ;
		 [field-><f1>:=&("m->"+<"f1">)];
		 [;field-><fn>:=&("m->"+<"fn">)]


#command GATHER MEMVAR ;
		[<mm: MEMO>]        =>  ;
                ;PRIVATE ___lch,___m_f                  ;
		;FOR ___lch:=1 TO FCount() 		;
  		;  ___m_f:="m->"+FieldName(___lch)      ;
		;  IIF(Type(___m_f)!="U",IIF(<.mm.> .or. FieldType(___lch)!="M",FieldPut(___lch,&___m_f)),);
		;NEXT

#command GATHER FROM <arr> ;
		[<mm: MEMO>]        =>  ;
                ;PRIVATE ___lch1                  ;
		;FOR ___lch1:=1 TO Len(<arr>)	 ;
		; IIF(<.mm.> .or. FieldType(___lch1)!="M",FieldPut(___lch1,<arr>\[___lch1\]),);	
		;NEXT						

#command SCAN 								;
	 [FOR <for>]                                                    ;
	 [WHILE <while>]                                                ;
	 [NEXT <next>]                                                  ;
	 [RECORD <rec>]                                                 ;
	 [<rest:REST>]                                                  ;
	 [<all:ALL>]                                                    ;
	 [<nooptimize:NOOPTIMIZE>]                                      ;
	 =>								;
	 ;PRIVATE lExit:=.F.					;
	 ;fox_ScanBegin( <"for"> , <{for}>, <{while}>, 			;
	 		<next>, <rec>, <.rest.>, <.nooptimize.>)	;
	 ; WHILE !EOF().AND.!lExit 				;
	 ;  IIF(!fox_ScanNext(),lExit:=.T.,)		

#command ENDSCAN => ;
	 ; END ;
	 ;fox_ScanEnd()


#command _USE <(db)>                                                     ;
	     [VIA <rdd>]                                                ;
	     [IN  <in>]                                                 ;
	     [ALIAS <alias>]                                                ;
	     [<new: NEW>]                                               ;
	     [<ex: EXCLUSIVE>]                                          ;
	     [<sh: SHARED>]                                             ;
	     [<ro: READONLY>]                                           ;
	     [ASCENDING]                                                ;
	     [<desc: DESCENDING>]                                       ;
	     [<noUpdate: NOUPDATE>]                                     ;
         [CODEPAGE <codepage>]                                      ;
	     [INDEX <ilist,...>]                                        ;
	     [ORDER  <(xOrder)>]                                        ;
	     [TAG    <cTag>]                                            ;
	     [OF     <xOf>]                                             ;
	     =>;
	     fox_useArea(<(db)>,<(alias)>,<rdd>,<in>,NIL , 			;
			<.new.>,iif(<.sh.> .or. <.ex.>, !<.ex.>, NIL),	;
			<.ro.>, <.noUpdate.>, <.desc.>,  		;
			{ <(ilist)> },<(xOrder)>,<"cTag">,<"xOf">,<codepage>)

// mini SQL commands

#command CREATE TABLE <(filename)> ;
		FROM [ARRAY] <arr> ;
		[VIA <ddriver>]    ;
		=> ;
		dbcreate(<(filename)>,<arr>,<ddriver>)

#command CREATE DBF <(filename)>   ;
		FROM [ARRAY] <arr> ;
		[VIA <ddriver>]    ;
		=> ;
		dbcreate(<(filename)>,<arr>,<ddriver>)

#command CREATE TABLE <(filename)> <(fields_data)>	;
		[VIA <ddriver>]   ;
		=> ;
	      fox_CreateTable(<(filename)>,<"fields_data">,<ddriver>)

#command INSERT INTO <(filename)> <(fields_data)> ;
		VALUES <valData> ;
		[VIA <ddriver>]    ;
		=> ;
	      fox_InsertData(<(filename)> , <"fields_data">,<"valData">,<ddriver>)

#command INSERT INTO <(filename)>  ;
		VALUES <valData> ;
		[VIA <ddriver>]    ;
		=> ;
	      fox_InsertData(<(filename)> , "", <"valData">,<ddriver>)

#command INSERT INTO <(filename)> <(data)>  ;
	     FROM ARRAY <valData>  ;
		[VIA <ddriver>]    ;
		=> ;
	      fox_InsertData(<(filename)>, <(data)>,<valData>,<ddriver>)

#command INSERT INTO <(filename)> ;
	     FROM ARRAY <valData>  ;
		[VIA <ddriver>]    ;
		=> ;
	      fox_InsertData(<(filename)>, "",<valData>,<ddriver>)

#command INSERT INTO <(filename)> <(data)>  ;
	     FROM MEMVAR           ;
		[VIA <ddriver>]    ;
		=> ;
	      fox_InsertData(<(filename)>,<(data)>,,<ddriver>)


#command INSERT INTO <(filename)> ;
	     FROM MEMVAR           ;
		[VIA <ddriver>]    ;
		=> ;
	      fox_InsertData(<(filename)>,"",,<ddriver>)
   
// 15.11.2012
#command GO TOP IN <cTableAlias> => <cTableAlias>->(DbGoTop())

#command GO BOTTOM IN <cTableAlias> => <cTableAlias>->(DbGoBottom())

#command GOTO <nRecno> IN <cTableAlias> => <cTableAlias>->(DbGoTo(<nRecno>))

#xtranslate RECCOUNT(<cTableAlias>) => <cTableAlias>->( RecCount() )
#xtranslate FCOUNT(<cTableAlias>) => <cTableAlias>->( FCount() )
#xtranslate FILTER(<cTableAlias>) => <cTableAlias>->( DbFilter() )

#xtranslate USED(<cTableAlias>) => <cTableAlias>->(Used())
#xtranslate USED(<nWorkArea>) => (<nWorkArea>)->(Used())

#command SET FILTER TO <cFilter> IN <cTableAlias> =>  ;
         <cTableAlias>->(DbSetFilter( <{cFilter}>, <"cFilter"> ))

#command SEEK <eExpression> [ORDER [TAG] <cTagName>] [IN <cTableAlias>] =>;
         FoxSEEK(<(eExpression)>, <(cTableAlias)>, <(cTagName)>)

#command SEEK <eExpression> [<soft: SOFTSEEK>] [<last: LAST>] TAG <cTagName> IN <cTableAlias> => ;
            fox_Seek(<(eExpression)>,<.soft.>, <.last.>,<(cTableAlias)>, <(cTagName)>)


// 17.11.2012
//		(<Columns,...>) ;
#command CREATE INDEX <(cIndexName)> ON <(cTableName)> <(cIndexExpresion)> [FOR <cForIndexExpresion>] [<uniq:UNIQUE>] [<desc: DESC>] ;
		=> ;
	      lsql_CreateIndex(<.uniq.>,<.desc.>,<(cIndexName)>,<(cTableName)>,<"cIndexExpresion">,<"cForIndexExpresion"> )



#command DELETE FROM <(cTableName)> [WHERE <cSearchCondition>] => ;
	      lsql_DeleteRows(<(cTableName)>,<"cSearchCondition">,<{cSearchCondition}>)

#command DROP INDEX <(cTableName)> <(cIndexName)> => ;
	      lsql_DropIndex(<(cTableName)>,<(cIndexName)>)

#command DROP TABLE <(cTableName)> => ;
	      lsql_DropTable(<(cTableName)>)

#command UPDATE <(cTableName)> SET <ColumnName1> = <ValData1> [,<ColumnNameN> = <ValDataN>] ;
              WHERE <cSearchCondition> => ;
		 lSelect:=_selectTable(<(cTableName)>,.T.)	;
         DBEval( {|| _FIELD-><ColumnName1> := <ValData1> [, _FIELD-><ColumnNameN> := <ValDataN>]}, ;
                 <{cSearchCondition}>)
//lsql_UpdateRows(<(cTableName)>,{|| <(ColumnName1)>,<(ValData1)>,[<(ColumnName1)>,<(ValData1)>]})


// 23.11.2012
#command SELECT <*x*> => fox_Select("select "+ \[<x>\])

//#command SELECT <*x*> INTO [ FILE | DBF | TABLE | PRINTER | ARRAY | HASH] <into_data>] => fox_Select("select "+ \[<x>\]+" INTO "+<"into_data">)
/*
#command SELECT <Fields_data> [AS <alias>] [, ...]  FROM <(from_data)> ;
				[WHERE <(FilterCondition)>];
				[GROUP BY <(group_data)>] [HAVING <(having_data)>] ;
				[ORDER BY <(orderby_data)>] ;
				[INTO [ FILE | DBF | TABLE | CURSOR | ARRAY | HASH] <(into_data)>];
				 => localSql_SelectQuery(<"Fields_data">,<"from_data">,<"FilterCondition">,<"group_data">,<"having_data">,<"orderby_data">,<"into_data">)
*/

/*
SELECT [ALL | DISTINCT] [TOP nExpr [PERCENT]] Select_List_Item [, ...]
   FROM [FORCE] Table_List_Item [, ...]
      [[JoinType] JOIN DatabaseName!]Table [[AS] Local_Alias]
      [ON JoinCondition [AND | OR [JoinCondition | FilterCondition] ...] 
   [WITH (BUFFERING = lExpr)]
   [WHERE JoinCondition | FilterCondition [AND | OR JoinCondition | FilterCondition] ...]
   [GROUP BY Column_List_Item [, ...]] [HAVING FilterCondition [AND | OR ...]]
   [UNION [ALL] SELECTCommand]
   [ORDER BY Order_Item [ASC | DESC] [, ...]]
   [INTO StorageDestination | TO DisplayDestination]
   [PREFERENCE PreferenceName] [NOCONSOLE] [PLAIN] [NOWAIT]
*/

#command ALTER TABLE <(cTableName)> ADD COLUMN <(cColumnName)> <(cDataType)> => ;
	      lsql_AlterTableAddCol(<(cTableName)>,<(cColumnName)>,<(cDataType)>)

#command ALTER TABLE <(cTableName)> DROP COLUMN <(cColumnName)> => ;
	      lsql_AlterTableDropCol(<(cTableName)>,<(cColumnName)>)

#command ALTER TABLE <(cTableName)> ALTER COLUMN <(cOldColumnName)> <(cNewColumnName)> => ;
	      lsql_AlterTableAlterCol(<(cTableName)>,<(cOldColumnName)>,<(cNewColumnName)>)


/* output query result */
#define  SQL_TO_NONE 	0
#define  SQL_TO_FILE 	1
#define  SQL_TO_CURSOR 	2
#define  SQL_TO_DBF 	3
#define  SQL_TO_TABLE 	3
#define  SQL_TO_PRINTER	4
#define  SQL_TO_ARRAY	5
#define  SQL_TO_HASH	6
#define  SQL_TO_OBJECT	6
#define  SQL_TO_ANYHASH  7  // result as MAP for subquery ANY,EXIST,ALL

/* direction in GROUP BY */
#define  SQL_DIRECTION_NONE  0
#define  SQL_DIRECTION_ASC   1
#define  SQL_DIRECTION_DESC  2

/* compare operation in WHERE operator */
#define  SQL_OPER_EXACTEQUAL  	1     // "v1 == v2 "
#define  SQL_OPER_EQUAL		2     // "v1 = v2 "
#define  SQL_OPER_NOTEQUAL  	3     // "v1 != v2 "
#define  SQL_OPER_GREAT 	4     // "v1 > v2 "
#define  SQL_OPER_GREATEQUAL 	5     // "v1 >= v2 "
#define  SQL_OPER_LESS	 	6     // "v1 < v2 "
#define  SQL_OPER_LESSEQUAL 	7     // "v1 <= v2 "
#define  SQL_OPER_PERCENT 	8     // "v1 % v2 "
#define  SQL_OPER_LIKE 		9     // "v1 LIKE v2"
#define  SQL_OPER_BETWEEN 	11    // "v1 BETWEEN c1 and c2"
#define  SQL_OPER_IN 		12    // "v1 IN v2"

#define  SQL_OPER_EXIST     	15     // "EXIST (select ...)"
//#define  SQL_OPER_NOTEXIST	16     // "NOT EXIST (select ..)"
#define  SQL_OPER_ALL   	17     // "v1 <oper> ALL <subquery>"
#define  SQL_OPER_ANY   	18     // "v1 <oper> ANY <subquery>"
#define  SQL_OPER_SOME   	18     // "v1 <oper> SOME <subquery>"

#define  SQL_OPER_SELECT   	100    // " select .. from (select from)"

/* subquery in  WHERE */
#define  SQL_OPER_GROUPOPEN   	21     // " ( "
#define  SQL_OPER_GROUPCLOSE   	22     // " )"

/* bulev operator in WHERE*/
#define  SQL_OPER_NOT		31     // " NOT "
#define  SQL_OPER_AND		32     // " AND "
#define  SQL_OPER_OR		33     // " OR "
#define  SQL_OPER_XOR		34     // " XOR "

/* subquery in  WHERE */

/* for optimization  WHERE constructions */
#define  SQL_TAG_NONE   	0      // empty tag
#define  SQL_TAG_LOGICAL   	1      // logical operation
#define  SQL_TAG_OPER   	2      // compare operation
#define  SQL_TAG_COMPARE   	3      // compare operation as Lvar <oper> Rval
#define  SQL_TAG_FUNC   	4      // call function
#define  SQL_TAG_FIELD   	5      // field value
#define  SQL_TAG_CONST   	6      // constant value
#define  SQL_TAG_SUBQUERY   	7      // subquery expression

#define  SQL_TAG_GROUP   	8      // group operation as ()

#define LANG_ARRAY_STRING	[array]
#define LANG_CBLOCK_STRING	[Block]
#define LANG_YES_STRING		[Yes]
#define LANG_NO_STRING		[No ]
#define LANG_YES_CHAR		[Y]
#define LANG_NO_CHAR		[N]
#define LANG_MEMO_STRING	[Memo]
#define LANG_OBJECT_STRING	[Object]
#define LANG_MAP_STRING		[Map]
#define LANG_UNDEF_STRING	[Undef]
#define LANG_UNKNOWN_STRING	[Unknown]

#ifdef __UNIX__
    #define CRLF    Chr(10)
    #define PATH_DELIM  "/"
#else
    #define CRLF    Chr(13) + Chr(10)
    #define PATH_DELIM  "\\"
#endif


#endif
